#import "BluetoothcontrollerPlugin.h"
#import "BlueUtil.h"
#import "callback/ScanCallback.h"
#import "callback/ConnectCallback.h"
#import "callback/ReceiverCallback.h"
#import "callback/WriteCallback.h"
#define CHANNEL_METHOD @"my.flutter.io/bluetooth"
#define EVENT_CHANNEL @"my.flutter.event/bluetooth"
@interface BluetoothcontrollerPlugin()<ScanCallback,ConnectCallback,ReceiverCallback,WriteCallback,FlutterStreamHandler>
@property (nonatomic,strong) FlutterEventSink myEventSink;//flutter中订阅了接收我发送的消息的观察者,因为ios取消监听的回调函数没有传eventSink对象进来，所以就不能用list来储存eventLink
@end

@implementation BluetoothcontrollerPlugin
+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
  FlutterMethodChannel* channel = [FlutterMethodChannel
      methodChannelWithName:CHANNEL_METHOD
            binaryMessenger:[registrar messenger]];
  BluetoothcontrollerPlugin* instance = [[BluetoothcontrollerPlugin alloc] init];
  [registrar addMethodCallDelegate:instance channel:channel];
    // 初始化FlutterEventChannel对象
    FlutterEventChannel *eventChannel = [FlutterEventChannel eventChannelWithName:EVENT_CHANNEL binaryMessenger:[registrar messenger]];
    [eventChannel setStreamHandler:instance];
    instance.blueControllerMap= [NSMutableDictionary new];//初始化储存蓝牙设备controller的数据字典
}

- (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
    if([@"connectDevice" isEqualToString: call.method]){//如果是要去连接设备的话
          NSLog(@"现在去连接设备了");
          NSDictionary * dataMap=call.arguments;
          BlueToothUtil * controller=[BlueToothUtil new];
          [controller setDeviceName:[dataMap objectForKey:@"deviceName"]];
          [controller setScanCallback:self];//设置扫描回调
          [controller setWriteCallback:self];//设置写入数据回调
          [controller setConnectCallback:self];//设置连接回调
          [controller setReceiverCallback:self];//设置notify回调
          [controller setKeepScanTime:10];//设置设备最大扫描时间
          [controller setUuid:[dataMap objectForKey:@"deviceUuid"]];//设置controller的设备uuid和要发现的服务uuid
          NSLog(@"deviceUuid:%@,serviceUuid:%@",[dataMap objectForKey:@"deviceUuid"],[dataMap objectForKey:@"serviceUuid"]);
          [_blueControllerMap setValue:controller forKey:[controller deviceName]];//将controller添加到数据字典中
          [controller connectPeripheral];//去连接设备
          result(@"80003");//跟flutter报告说去连接设备了
    }else if([@"sendData" isEqualToString: call.method]){//如果是要去发数据给设备
          NSDictionary * dataMap=call.arguments;
          BlueToothUtil * controller=[_blueControllerMap objectForKey:[dataMap objectForKey:@"deviceName"]];//获取目前要发数据的目标蓝牙设备controller
          FlutterStandardTypedData * dataByte=[dataMap objectForKey:@"data"];
          [controller sendDataToBLE:dataByte.data serviceUuid:[dataMap objectForKey:@"serviceUuid"] writeUuid:[dataMap objectForKey:@"writeUuid"] notifyUuid:[dataMap objectForKey:@"notifyUuid"] isEnable:[dataMap objectForKey:@"isWithResult"]];//向设备发送数据
    }else if([@"disConnectDevice" isEqualToString: call.method]){//如果是要去手动断开连接
          NSLog(@"要求手动断开连接啦");
          BlueToothUtil * controller=[_blueControllerMap objectForKey:(NSString *)call.arguments];//获取目前要发数据的目标蓝牙设备controller
          [controller disConnectPeripheral];//与当前设备断开连接
      }else
          result(FlutterMethodNotImplemented);//没有此方法
  }];
}

- (void)onScanning:(BlueToothUtil *)controller {//正在扫描的回调
    NSLog(@"扫描到一个");
}

- (void)scanFinish:(BlueToothUtil *)controller{//扫描成功的回调
    if(![controller isScanTarget]){//如果扫描不到设备
        NSLog(@"扫描不到目标设备");
        NSString * deviceName=[controller deviceName];//获取到controller的deviceName,目前这里暂时还没有什么用
        [_blueControllerMap removeObjectForKey:deviceName];//将controller从map中移除
        [self sendDataToFlutter:[FlutterError errorWithCode:@"90001" message:@"扫描不到目标设备" details:[controller deviceName]]];
    }
}

- (void)connectFailed :(BlueToothUtil *)controller{//连接失败的回调
    [self.blueControllerMap removeObjectForKey:[controller deviceName]];//将controller从map中移除
    [self sendDataToFlutter:[FlutterError errorWithCode:@"90002" message:@"与设备的连接断开" details:[controller deviceName]]];
}

- (void)connectSuccess :(BlueToothUtil *)controller{//连接成功的回调
    NSDictionary<NSString *,id> * successData=[[NSDictionary alloc]
                                               initWithObjectsAndKeys:
                                               @"80001", @"code",
                                               [controller deviceName],@"deviceName",nil];//因为NSDictionary不可改变，所以一定要这样初始化
    [self sendDataToFlutter:successData];
}

- (void)disConnect :(BlueToothUtil *)controller{//断开连接的回调
    if([controller isInitiativeDisconnect]){//如果是主动去断开连接的话
        NSLog(@"连接被手动断开");
        NSDictionary<NSString *,id> * successData=[[NSDictionary alloc]
                                                   initWithObjectsAndKeys:
                                                   @"80002",@"code",
                                                   [controller deviceName],@"deviceName",nil];//因为NSDictionary不可改变，所以一定要这样初始化
        [self.blueControllerMap removeObjectForKey:[controller deviceName]];//将controller从map中移除
        [self sendDataToFlutter:successData];
    }else{//如果是自动断开的话
        NSLog(@"连接被自动断开");
        [self.blueControllerMap removeObjectForKey:[controller deviceName]];//将controller从map中移除
        [self sendDataToFlutter:[FlutterError errorWithCode:@"90002" message:@"与设备的连接断开" details:[controller deviceName]]];
    }
}

- (void)onReceiver:(NSString *)characteristicUuid data:(NSData *)data controller:(BlueToothUtil *)controller {//接收到蓝牙设备传回来的回调
    //Byte * byteData=[data bytes];//data是NSInlineData这个数据类型
    FlutterStandardTypedData * flutterData=[FlutterStandardTypedData typedDataWithBytes:data];
    NSLog(@"notify的特征值(%@),返回的数据大小(%d)",characteristicUuid,flutterData.elementSize);
    NSDictionary<NSString *,id> * successData=[[NSDictionary alloc]
                                               initWithObjectsAndKeys:
                                               @"80005", @"code",
                                               [controller deviceName],@"deviceName",
                                               characteristicUuid,@"notifyUuid",
                                               flutterData,@"data",nil];//因为NSDictionary不可改变，所以一定要这样初始化
    [self sendDataToFlutter:successData];//向flutter发送notify传回来的数据
}

- (void)writeFailed:(NSString *)characteristicUuid {//写入数据失败的回调
    
}

- (void)writeSuccess:(NSString *)characteristicUuid {//写入数据成功的回调
    NSLog(@"写入数据成功");
}

-(void)sendDataToFlutter:(id) data{//向flutter发送数据
    if(self.myEventSink!=nil)
        self.myEventSink(data);
}

#pragma mark - FlutterStreamHandler
- (FlutterError* _Nullable)onListenWithArguments:(id _Nullable)arguments
                                       eventSink:(FlutterEventSink)eventSink{//当flutter向监听我们的channel时调用的函数
    self.myEventSink=eventSink;//设置观察者
    return nil;
}
 
- (FlutterError* _Nullable)onCancelWithArguments:(id _Nullable)arguments {//flutter取消对我们的监听时调用的函数
    self.myEventSink=nil;//删除观察者
    return nil;
}

@end
